#include <iostream>
#include <fstream>
#include <string>
#include <GL/glew.h>
#include <GL/glfw.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include "application.h"
#include "IDrawEvent.h"
#include "IUpdateEvent.h"
#include "vertex.h"
#include "movingpolygon.h"
#include "Collider.h"

using namespace std;

void Application::Init(){
	if(!glfwInit())
		cout << "Failed to initialize GLFW\n";
	
	if(!glfwOpenWindow(1024, 768, 0,0,0,0, 32,0, GLFW_WINDOW))
	{
		cout << "Failed to open GLFW window\n";
		glfwTerminate();
	}

 	glewExperimental = GL_TRUE;

	if (glewInit() != GLEW_OK) 
		cout << "Failed to initialize GLEW\n";
	
	glfwEnable(GLFW_STICKY_KEYS);

	glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LEQUAL);
	glClearColor(0.4, 0.4, 0.4, 1.0);
	Collider::get_Instance();
	DrawScene("scene1.txt");
	
}

void Application::DrawScene(const char* file_name){
	ifstream file;
	string str;
	Vertex v, t;
	char* fname = new char [20];
	int n;
	float a, d, m, I;

    file.open(file_name);

	if (file.is_open()) {
        file >> n;
		for (int i = 0; i < n; i++){
			file >> v;
			file >> a;
			file >> d;
			file >> m;
			file >> I;
			file >> t;
			file >> str;
			strcpy(fname, str.c_str());

			MovingPolygon *p = new MovingPolygon(fname);
			p->SetCenter(v);			
			p->SetAngle(a);			
			p->SetdAngle(d);
			p->SetM(m);
			p->SetI(I);
			p->SetT(t);
			p->CalcRotMatrix();
		}
		
		file >> n;
		for (int i = 0; i < n; i++){
			file >> v;
			file >> a;
			file >> m;
			file >> I;
			file >> str;
			strcpy(fname, str.c_str());

			Polygon *p = new Polygon(fname);
			p->SetCenter(v);			
			p->SetAngle(a);	
			p->SetM(m);
			p->SetI(I);
			p->CalcRotMatrix();
		}

        file.close();
    }
	delete [] fname;
}

void Application::Draw(){
	
	IDrawEvent::drawAll();
}

void Application::Update(double time){
	glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
	glViewport(0, 0, 1024, 768);
	glClearColor(0.4, 0.4, 0.4, 1.0);
	//Collider::
	IUpdateEvent::fireEvent(time);
}

void Application::Run(){
	double start_time, frame_time = 0;
	while((glfwGetKey(GLFW_KEY_ESC) != GLFW_PRESS) && glfwGetWindowParam(GLFW_OPENED)){ 
		
		start_time = glfwGetTime();
		Update(frame_time);
		Draw();

		frame_time = glfwGetTime() - start_time;
		//glfwSleep(time);

		glfwSwapBuffers();		
	}
	glfwTerminate();
}

void Application::Destroy(){
	
}

Application *Application::instance = NULL;